package com.bracketbird.client.model;


import com.bracketbird.client.*;
import com.bracketbird.client.model.keys.*;
import com.bracketbird.client.model.tournament.*;
import com.bracketbird.clientcore.model.*;

import java.util.*;

/**
 *
 */
public class PlayingTeam extends Model<PlayingTeamId> {
    private static final long serialVersionUID = -8413373363468003258L;

    private transient List<TournamentListener<TournamentTeamEvent>> teamListener = new ArrayList<TournamentListener<TournamentTeamEvent>>();
    private List<MemberId> members = new ArrayList<MemberId>();
    private List<String> nonMembers = new ArrayList<String>();

    private Date createdDate;
    private TournamentId tournamentId;
    private String teamName;


    //used and generated on client only (when laying out teams)
    private transient String teamNameNumber;


    private transient String teamNameByPlayers;
    private String info;
    private Integer seeding;

    public PlayingTeam() {
        super();
    }

    @Override
    public PlayingTeamId createLocalId() {
        return new PlayingTeamId();
    }


    public List<MemberId> getMembers() {
        return members;
    }

    public void setMembers(List<MemberId> members) {
        this.members = members;
    }

    public Integer getSeeding() {
        return seeding;
    }

    public void setSeeding(Integer seeding) {
        this.seeding = seeding;
    }


    private void fireTeamChangeEvent(boolean fromClient) {
        TournamentTeamEvent e = new TournamentTeamEvent(fromClient, this, TournamentTeamEvent.Action.update);
        for (TournamentListener<TournamentTeamEvent> l : teamListener) {
            l.onChange(e);
        }
    }

    public void addTeamsListener(TournamentListener<TournamentTeamEvent> l) {
        teamListener.add(l);
    }


    public String getTeamNameNumber() {
        return teamNameNumber;
    }

    public void setTeamNameNumber(String teamNameNumber) {
        this.teamNameNumber = teamNameNumber;
    }

    public String getTeamName() {
        return teamName;
    }


    public void setTeamName(String teamName) {
        this.teamName = teamName;
        //fireTeamChangeEvent(true);
    }

    private void createTeamNameByPlayers() {
        StringBuffer sb = new StringBuffer();

        for (MemberId member : members) {
            if (sb.length() != 0) {
                sb.append(" & ");
            }
            sb.append(UserManager.getInstance().getMember(member).getShortName());
        }

        for (String nonMember : nonMembers) {
            if (sb.length() != 0) {
                sb.append(" & ");
            }
            sb.append(nonMember);
        }
        teamNameByPlayers = sb.toString();
    }


    public List<String> getNonMembers() {
        return nonMembers;
    }

    public void setNonMembers(List<String> nonMembers) {
        this.nonMembers = nonMembers;
    }

    public void addMember(MemberId id) {
        members.add(id);
    }

    public void addNonMember(String mString) {
        nonMembers.add(mString);
    }

    public void removeMember(MemberId id) {
        members.remove(id);
    }

    public void removeNonMember(String playerName) {
        nonMembers.remove(playerName);
    }

    public boolean isEmpty() {
        return teamName == null || teamName.equals("");
    }

    public PlayingTeamVO createVO() {
        PlayingTeamVO vo = new PlayingTeamVO();
        vo.setMembers(new ArrayList<MemberId>(getMembers()));
        vo.setNonMembers(new ArrayList<String>(getNonMembers()));
        vo.setInfo(getInfo());
        vo.setTeamName(getTeamName());
        vo.setSeeding(getSeeding());

        return vo;
    }


    public void update(PlayingTeamVO vo, boolean fromClient) {
        setMembers(new ArrayList<MemberId>(vo.getMembers()));
        setNonMembers(new ArrayList<String>(vo.getNonMembers()));
        setInfo(vo.getInfo());
        setTeamName(vo.getTeamName());
        setSeeding(vo.getSeeding());
        createTeamNameByPlayers();
        fireTeamChangeEvent(fromClient);
    }


    public TournamentId getTournamentId() {
        return tournamentId;
    }

    public void setTournamentId(TournamentId tournamentId) {
        this.tournamentId = tournamentId;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getMostQualifiedTeamName() {
        if (teamName != null && !teamName.equals("")) {
            return teamName;
        }

        return (getMembers().size() + getNonMembers().size() > 2) ? teamNameNumber : teamNameByPlayers;
    }


    public static boolean isTeamNameValid(String name) {

        if (name == null || name.equals("")) {
            return false;
        }
        String[] split = name.split(" ");
        if (split == null || split.length != 2) {
            return true;
        }
        try {
            Integer.valueOf(split[1]);
            return !split[0].equals("Team");
        }
        catch (Exception e) {
            return true;
        }
    }

    @Override
    public String toString() {
        return "PlayingTeam{" +
                ", teamName=" + teamName +
                ", teamNameNumber=" + teamNameNumber +
                ", teamNameByPlayers=" + teamNameByPlayers +
                ", members=" + members +
                ", nonMembers=" + nonMembers +
                '}';
    }

    public int compareToByCreatedDate(PlayingTeam pt) {
        if (this.getCreatedDate() == null) {
            return -1;
        }
        return new Long(getCreatedDate().getTime()).compareTo(pt.getCreatedDate().getTime());
    }

    public boolean isWalkover() {
        return this instanceof WalkOverTeam;
    }

    public boolean hasSeeding() {
        return seeding != null;
    }
}
